"use strict";

module.exports = core;

const path = require("path");

const semver = require("semver");
const colors = require("colors/safe");
const userHome = require("user-home");
const pathExists = require("path-exists").sync;
const {
    Command
} = require("commander");
const log = require("@sue-cli-dev/log");
const init = require("@sue-cli-dev/init")
const exec = require("@sue-cli-dev/exec")

const pkg = require("../package.json");
const constant = require("./const");

let args;

const program = new Command();

async function core() {
    // TODO
    try {
        await prepare()
        registerCommand();
    } catch (error) {
        log.error(error.message);
    }
}

function registerCommand() {
    program
        .name(Object.keys(pkg.bin)[0])
        .usage("<command> [option]")
        .version(pkg.version)
        .option("-d, --debug", "是否开启调试模式", false)
        .option("-tp, --targetPath <targetPath>", "是否指定本地调试文件路径", '')

    program
        .command("init [projectName]")
        .option("-f, --force", "是否初始化项目")
        .action(exec);

    // 开启debug模式
    program.on("option:debug", function () {
        if (program.debug) {
            process.env.LOG_LEVEL = "verbose";
        } else {
            process.env.LOG_LEVEL = "info";
        }

        log.level = process.env.LOG_LEVEL;
    });

    // 指定targetPath
    program.on("option:targetPath", function () {
        process.env.CLI_TARGET_PATH = program.targetPath
    })

    // 对未知命令监听
    program.on("command:*", function (obj) {
        const availableCommands = program.commands.map((cmd) => cmd.name());
        console.log(colors.red("未知命令：" + obj[0]));
        if (availableCommands.length > 0) {
            console.log(colors.red("可用命令：" + availableCommands.join(",")));
        }
    });

    if (process.argv.length < 3) {
        program.outputHelp();
        console.log();
    }
    program.parse(process.argv);
}

async function prepare() {
    checkPkgVersion();
    checkNodeVersion();
    checkRoot();
    checkUserHome();
    checkEnv();
    await checkGlobalUpdate();
}

async function checkGlobalUpdate() {
    // 获取当前版本号和模块名
    const currentVersion = pkg.version;
    const npmName = pkg.name;
    // 调用 npm API 获取所有版本号
    // 提取所有版本号，比对哪些版本号是大于当前版本号
    // 获取最新版本号，提示用户更新到该版本
    const {
        getNpmSemverVersion
    } = require("@sue-cli-dev/get-npm-info");
    const lastVersion = await getNpmSemverVersion(currentVersion, npmName);
    if (lastVersion && semver.gt(lastVersion, currentVersion)) {
        log.warn(
            colors.yellow(
                `请手动更新 ${npmName}，当前版本 ${currentVersion}, 最新版本 ${lastVersion}, 更新命令 npm install -g ${npmName}`
            )
        );
    }
}

function checkEnv() {
    const dotEnv = require("dotenv");
    const dotPath = path.resolve(userHome, ".env");
    if (pathExists(dotPath)) {
        dotEnv.config({
            path: dotPath,
        });
    }
    checkDefaultConfig();
    log.verbose("环境变量", process.env.CLI_HOME_PATH);
}

function checkDefaultConfig() {
    const cliConfig = {
        home: userHome,
    };
    if (process.env.CLI_HOME) {
        cliConfig["cliHome"] = path.join(userHome, process.env.CLI_HOME);
    } else {
        cliConfig["cliHome"] = path.join(userHome, constant.DEFAULT_CLI_HOME);
    }
    process.env.CLI_HOME_PATH = cliConfig.cliHome;
}

function checkArgs() {
    if (args.debug) {
        process.env.LOG_LEVEL = "verbose";
    } else {
        process.env.LOG_LEVEL = "info";
    }
    log.level = process.env.LOG_LEVEL;
}

function checkUserHome() {
    if (!userHome || !pathExists(userHome)) {
        throw new Error(color.red("当前登录用户主目录不存在！"));
    }
}

function checkRoot() {
    const rootCheck = require("root-check");
    rootCheck();
}

function checkPkgVersion() {
    log.notice("cli", pkg.version);
}

function checkNodeVersion() {
    // 获取当前版本号
    const currentVersion = process.version;
    // 比对最低版本号
    const lowestVersion = constant.LOWEST_NODE_VERSION;
    if (!semver.gte(currentVersion, lowestVersion)) {
        throw new Error(
            colors.red(`sue-cli-dev 需要安装 v${lowestVersion} 以上版本的Nodejs`)
        );
    }
}
